package main.model.critters;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import main.model.critters.eventprocessor.CritterEventProcessorImp;
import main.model.critters.genetics.BreedCritters;
import main.model.critters.genetics.Chromosome;
import main.model.critters.genetics.Sex;
import main.model.critters.listener.CritterListener;
import main.model.hexisland.HexIsland;
import main.model.island.IslandInterface;


public class CritterCensus extends CritterEventProcessorImp {
	private static final Logger LOG = Logger.getLogger(CritterCensus.class.getName());



    private HexIsland island;
	private Collection<Critter> critterList = new ArrayList<Critter>();
    private Collection<Critter> deadList = new ArrayList<Critter>();
	private LocationValidator locationValidator;
	
	public CritterCensus(HexIsland island){
		LOG.setLevel(Level.FINEST);
        this.island = island;
		locationValidator = new LocationValidator(this);
	}

    public void recheckLocations(){
        critterList.removeAll(deadList);
        locationValidator.checkAllCritters();

    }
	
	private void remove(Critter c){
		deadList.add(c);
		LOG.fine("Preparing to remove critter "+c.getIdentity()+" from the critter census.");
        fireDeathEvent(c);
	}

    public Collection<Critter> getCritters(){
        if(critterList == null) critterList = new ArrayList<Critter>();
        return critterList;
    }

	private void add(Critter c){
        if(c == null) return;
		c.addCritterListener(new CritterListener(){
			public void deathEvent(Critter cadaver) {
				remove(cadaver);
			}
			public void birthEvent(Critter infant) {}
			public void huntEvent(Critter predator, Critter prey) {}
		});
		critterList.add(c);
		LOG.fine("Added critter "+c.getIdentity()+" to the critter census.");
		fireBirthEvent(c);
	}
	
	public void generateGenesis(int litter){
		Critter eve = CritterFactory.randomHomogenousCritter(Sex.FEMALE);
		add(eve);
		
		for(int i =0; i<litter;i++){
			Chromosome a = CritterFactory.generateChromosome(eve);
			Chromosome b = CritterFactory.generateChromosome(eve);
			Critter c = new Critter(a,b,eve.getSpecies(),CritterFactory.randomSex());
			add(c);
		}
		locationValidator.checkAllCritters();
	}

	public void breedCritters(Critter mother, Critter father){
		Critter c = BreedCritters.breed(mother,father);
		add(c);
	}


    public HexIsland getIsland() {
        return island;
    }
}
